package com.bsi.rd.framework.zuul.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName AttackTackle
 * @Author LiuSong
 * @Date 2020/5/13 16:57
 * @Version 1.0
 * @Description 拦截所有请求中是否带特殊字符
 */
public class AttackTackleUtil {
    private static final Log log = LogFactory.getLog(AttackTackleUtil.class);

    private static Pattern SCRIPT_PATTERN = Pattern.compile("<script.*>.*<\\/script\\s*>");
    private static Pattern HTML_PATTERN = Pattern.compile("<[^>]+>");

    public static boolean doTackle(HttpServletRequest request, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Cache-Control", "no-store");
        response.setDateHeader("Expires", 0L);

        Map paramMap = request.getParameterMap();
        int flag = -1;
        String lowStr = null;
        Set keSet = paramMap.entrySet();

        // 获取请求路径的接口地址
        String urlPath = request.getRequestURI();

        for (Iterator itr = keSet.iterator(); itr.hasNext(); ) {
            Map.Entry me = (Map.Entry) itr.next();
            Object ok = me.getKey();
            if(ok.equals("token") || ok.equals("password")){
                continue;
            }
            Object ov = me.getValue();
            String[] value = new String[1];
            if ((ov instanceof String[])){
                value = (String[]) ov;
            } else {
                value[0] = ov.toString();
            }
            for (int k = 0; k < value.length; k++) {
                lowStr = value[k];
                if (StringUtils.isNotBlank(lowStr)) {
                    lowStr = lowStr.toLowerCase();
                }

                Matcher mHtml = HTML_PATTERN.matcher(lowStr);
                if (mHtml.find()) {
                    flag = 1;
                }

                Matcher m = SCRIPT_PATTERN.matcher(lowStr);
                if (m.find()) {
                    flag = 1;
                }

                if ((lowStr.contains("ascii(")) || (lowStr.contains("ascii (")) ||
                        (lowStr.contains("chr(")) || (lowStr.contains("chr ("))) {
                    flag = 1;
                }

                if ((lowStr.contains("alter")) || (lowStr.contains("create")) ||
                        (lowStr.contains("ALERT")) ||
                        (lowStr.contains("CREATE")) ||
                        (lowStr.contains("truncate")) ||
                        (lowStr.contains("drop")) ||
                        (lowStr.contains("lock table")) ||
                        (lowStr.contains("insert")) ||
                        (lowStr.contains("update")) ||
                        (lowStr.contains("delete")) ||
                        (lowStr.contains("select")) || (lowStr.contains("from")) ||
                        (lowStr.contains("union")) || (lowStr.contains("where")) ||
                        (lowStr.contains("execute")) ||
                        (lowStr.contains("exec")) ||
                        (lowStr.contains("immedicate")) ||
                        (lowStr.contains("1=1")) || (lowStr.contains("1 = 1")) ||
                        (lowStr.contains("table")) || (lowStr.contains("into")) ||
                        (lowStr.contains("all")) || (lowStr.contains("or")) ||
                        (lowStr.contains("and")) ||
                        (lowStr.contains("dbms")) ||
                        (lowStr.contains("TRUNCATE")) ||
                        (lowStr.contains("DROP")) ||
                        (lowStr.contains("LOCK TABLE")) ||
                        (lowStr.contains("INSERT")) ||
                        (lowStr.contains("UPDATE")) ||
                        (lowStr.contains("DELETE")) ||
                        (lowStr.contains("SELECT")) ||
                        (lowStr.contains("GRANT")) || (lowStr.contains("FROM")) ||
                        (lowStr.contains("UNION")) || (lowStr.contains("WHERE")) ||
                        (lowStr.contains("EXECUTE")) ||
                        (lowStr.contains("EXEC")) ||
                        (lowStr.contains("IMMEDICATE")) ||
                        (lowStr.contains("execute")) ||
                        (lowStr.contains("TABLE")) || (lowStr.contains("INTO")) ||
                        (lowStr.contains("ALL")) || (lowStr.contains("OR")) ||
                        (lowStr.contains("AND")) ||
                        (lowStr.contains("DBMS"))) {
                    flag = 1;
                }

                if ((lowStr.contains("onclick")) || (lowStr.contains("alert")) ||
                        (lowStr.contains("document")) ||
                        (lowStr.contains("write")) || (lowStr.contains("param")) ||
                        (lowStr.contains("append")) ||(lowStr.contains("tabName")) ||
                        (lowStr.contains("onchange")) ||
                        /*(lowStr.contains("%")) ||*/
                        (lowStr.contains("break")) ||
                        (lowStr.contains("return")) ||
                        /*(lowStr.contains("continue")) ||*/
                        (lowStr.contains("debugger")) ||
                        (lowStr.contains("function")) ||
                        (lowStr.contains("this")) ||
                        (lowStr.contains("onabort")) ||
                        (lowStr.contains("onblur")) ||
                        (lowStr.contains("ondblclick")) ||
                        (lowStr.contains("onerror")) ||
                        (lowStr.contains("onfocus")) ||
                        (lowStr.contains("onkeydown")) ||
                        (lowStr.contains("onkeypress")) ||
                        (lowStr.contains("onkeyup")) ||
                        (lowStr.contains("onload")) ||
                        (lowStr.contains("onmousedown")) ||
                        (lowStr.contains("onmousemove")) ||
                        (lowStr.contains("onmouseout")) ||
                        (lowStr.contains("onmouseover")) ||
                        (lowStr.contains("onmouseup")) ||
                        (lowStr.contains("onresize")) ||
                        (lowStr.contains("onreset")) ||
                        (lowStr.contains("onselect")) ||
                        (lowStr.contains("onsubmit")) ||
                        (lowStr.contains("onunload")) ||
                        (lowStr.contains("prompt")) || (lowStr.contains("eval")) ||
                        (lowStr.contains("ONCLICK")) ||
                        (lowStr.contains("ALERT")) ||
                        (lowStr.contains("DOCUMENT")) ||
                        (lowStr.contains("WRITE")) || (lowStr.contains("PARAM")) ||
                        (lowStr.contains("APPEND")) ||  (lowStr.contains("TABNAME")) ||
                        (lowStr.contains("ONCHANGE")) ||
                        (lowStr.contains("BREAK")) ||
                        (lowStr.contains("RETURN")) ||
                        (lowStr.contains("CONTINUE")) ||
                        (lowStr.contains("DEBUGGER")) ||
                        (lowStr.contains("FUNCTION")) ||
                        (lowStr.contains("THIS")) ||
                        (lowStr.contains("ONABORT")) ||
                        (lowStr.contains("ONBLUR")) ||
                        (lowStr.contains("ONDBLCLICK")) ||
                        (lowStr.contains("ONERROR")) ||
                        (lowStr.contains("ONFOCUS")) ||
                        (lowStr.contains("ONKEYDOWN")) ||
                        (lowStr.contains("ONKEYPRESS")) ||
                        (lowStr.contains("ONKEYUP")) ||
                        (lowStr.contains("ONLOAD")) ||
                        (lowStr.contains("ONMOUSEDOWN")) ||
                        (lowStr.contains("ONMOUSEMOVE")) ||
                        (lowStr.contains("ONMOUSEOUT")) ||
                        (lowStr.contains("ONMOUSEOVER")) ||
                        (lowStr.contains("ONMOUSEUP")) ||
                        (lowStr.contains("ONRESIZE")) ||
                        (lowStr.contains("ONRESET")) ||
                        (lowStr.contains("ONSELECT")) ||
                        (lowStr.contains("ONSUBMIT")) ||
                        (lowStr.contains("ONUNLOAD")) ||
                        (lowStr.contains("PROMPT")) || (lowStr.contains("EVAL"))) {
                    flag = 1;
                }

                if (/*(lowStr.contains("!")) || (lowStr.contains("|")) ||
                        (lowStr.contains("$")) || (lowStr.contains("&")) ||
                        (lowStr.contains("'")) ||(lowStr.contains("\"")) ||*/
                        /*(lowStr.contains("<")) || (lowStr.contains(">")) ||*/
                        (lowStr.contains("script")) ||
                        (lowStr.contains("request")) ||
                        (lowStr.contains("response")) ||
                        (lowStr.contains("getParameter")) ||
                        (lowStr.contains("getCookies")) ||
                        /*(lowStr.contains("CR")) || (lowStr.contains("cr")) ||*/
                        (lowStr.contains("LF")) || (lowStr.contains("GET")) ||
                        (lowStr.contains("get")) || (lowStr.contains("post")) ||
                        (lowStr.contains("POST")) || (lowStr.contains("User")) ||
                        (lowStr.contains("Referer")) ||
                        (lowStr.contains("Accept")) ) {
                    flag = 1;
                }

                if (flag == 1) {
                    return false;
                }
            }
        }
        return true;
    }
}
